home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 2
/
Meeting Pearls Vol. II (1995)(GTI - Schatztruhe)[!].iso
/
Pearls
/
arc
/
XFH
/
src
/
xfhsrc
/
xfh.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-14
|
30KB
|
1,499 lines
/* prima di ogni SetGadgetAttrs() verificare che il gadget sia attaccato */
/* creare dinamicamente anche i primarygadgets oltre ai secondarygadgets */
/* mostrare requester se non c'e` xpkmaster 2.2 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/devices.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <workbench/startup.h>
#include <libraries/dosextens.h>
#include <libraries/gadtools.h>
#include <libraries/xpk.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/commodities.h>
#include <proto/icon.h>
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include "xfhsem.h"
CxObj __stdargs *HotKey( STRPTR description, struct MsgPort *port, long id );
UBYTE versionstring20[] = "\0$VER: xfh 1.01 (14.12.92)";
#define WINDOWWIDTH 466L
#define PACKERDESCCHARS 39
#define DEVLISTCHARS 50
struct MyXPINFO
{
struct Node nd;
XPINFO xpinfo;
};
struct MyXFHNode
{
struct Node nd;
struct XFHNode xfh;
};
#define POP_KEY_ID (86L) /* pop up identifier */
UBYTE iconname[] = "PROGDIR:XFH";
UBYTE lowmemtxt[] = "LOWMEM";
UBYTE compresstxt[] = "COMPRESS";
UBYTE hotkeybuff[257];
UBYTE windowtitle[130];
WORD dontpop;
enum { DEVLISTID = 1, LOWMEMID, AUTOPACKID, SELECTPACKERID,
PACKERLISTID, EFFICID, OKID, CANCELID };
struct GfxBase *GfxBase;
struct IntuitionBase *IntuitionBase;
struct Library *GadToolsBase;
struct Library *CxBase;
struct Library *IconBase;
struct Library *XpkBase;
struct WBStartup *WBenchMsg;
struct Screen *screen;
struct Window *window;
struct Menu *menu;
APTR vi;
struct TextFont *topazfont;
struct Gadget *glist1,*glist2,*devlistgad,*lowmemgad,*autopackgad,*selectpackergad,
*packernamegad,*packerlistgad,*desc1gad,*desc2gad,*desc3gad,*efficgad,
*modegad,*cfgad,*psgad,*usgad;
UBYTE modestr[10],cfstr[5],psstr[10],usstr[10];
WORD displayedgads; /* 0 no gadgets, 1 primary set, 2 secondary set */
struct List xfhlist;
struct List packerlist;
struct MyXFHNode *selecteddevice;
LONG numselecteddevice = ~0L;
struct MyXPINFO *selectedpacker;
LONG numselectedpacker = ~0L;
CxObj *broker;
struct NewBroker mynb =
{
NB_VERSION,
"XFH",
"XFH Controller:",
"Control XFH Features",
NBU_NOTIFY | NBU_UNIQUE,
COF_SHOW_HIDE,
};
struct MsgPort *cxport; /* commodities messages here */
ULONG cxsigflag = 0; /* signal for above */
LONG winleft = -1;
LONG wintop = -1;
enum {MEN_SAVE=1,MEN_HIDE,MEN_QUIT};
struct NewMenu menudef[] =
{
{ NM_TITLE, "Project", 0, 0, 0, (APTR)0 },
{ NM_ITEM, "Save", "S", 0, 0, (APTR)MEN_SAVE },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, (APTR)0 },
{ NM_ITEM, "Hide", "H", 0, 0, (APTR)MEN_HIDE },
{ NM_ITEM, "Quit", "Q", 0, 0, (APTR)MEN_QUIT },
{ NM_END, 0, 0, 0, 0, (APTR)0 }
};
struct TextAttr tanormal =
{
"topaz.font",
8,
FS_NORMAL,
FPF_ROMFONT,
};
struct Window *openwindow(VOID);
LONG createmaingadgets(VOID);
LONG createsecondarygadgets(VOID);
VOID closewindow(VOID);
VOID builddevslist(VOID);
VOID buildpackerslist(VOID);
VOID ClearWindow(struct Window *win);
VOID PrintInfoSelectedDevice(VOID);
VOID PrintInfoSelectedPacker(VOID);
VOID PrintInfoSelectedMode(VOID);
struct XFHSemaphore *GetSemaphore(VOID);
VOID InitXFHSemaphore(VOID);
VOID saveconfig(VOID);
VOID updatesemaphore(struct MyXFHNode *nd);
VOID notifyhandler(struct XFHNode *node);
VOID AddAlpha(struct List *list,struct Node *node);
VOID FreeList(struct List *list);
VOID cleanup(LONG code);
BOOL setupCX(VOID);
VOID shutdownCX(VOID);
void __stdargs __main(char *stub)
{
ULONG recsignal,windowsignal;
struct Process *process;
WORD done = 0;
ULONG cl = 0;
UWORD code;
struct IntuiMessage *msg;
struct Gadget *gadg;
CxMsg *cxmsg;
extern struct WBStartup *WBenchMsg;
NewList(&xfhlist);
NewList(&packerlist);
if (!(process = (struct Process *)FindTask(NULL))->pr_CLI) /* from Workbench */
{
WaitPort(&process->pr_MsgPort);
WBenchMsg = (struct WBStartup *)GetMsg(&process->pr_MsgPort);
}
if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37)) ||
!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37)) ||
!(GadToolsBase = OpenLibrary("gadtools.library",37)) ||
!(CxBase = OpenLibrary("commodities.library",37)) ||
!(IconBase = OpenLibrary("icon.library",37)) ||
!(XpkBase = OpenLibrary(XPKNAME,2)))
cleanup(RETURN_FAIL);
strcpy(hotkeybuff,"control alt x");
strcpy(windowtitle,"XFH: Hot Key = <");
if (WBenchMsg) /* from Workbench */
{
struct WBArg *wbarg;
struct DiskObject *dskobj;
BPTR curdir;
wbarg = WBenchMsg->sm_ArgList;
curdir = CurrentDir(wbarg->wa_Lock);
if (dskobj = GetDiskObject((UBYTE *)wbarg->wa_Name))
{
UBYTE *tt;
if (tt = FindToolType(dskobj->do_ToolTypes,"CX_PRIORITY"))
{
LONG val;
StrToLong(tt,&val);
mynb.nb_Pri = val;
}
if (tt = FindToolType(dskobj->do_ToolTypes,"CX_POPKEY"))
strncpy(hotkeybuff,tt,256);
if (tt = FindToolType(dskobj->do_ToolTypes,"CX_POPUP"))
if (!stricmp(tt,"NO")) dontpop = 1;
FreeDiskObject(dskobj);
}
CurrentDir(curdir);
}
else /* from CLI */
{
struct RDArgs *rdargs = 0;
LONG argarray[3];
argarray[0] = argarray[1] = argarray[2] = 0;
if (rdargs = ReadArgs("CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/K",
argarray,NULL))
{
if (argarray[0]) mynb.nb_Pri = *((LONG *)argarray[0]);
if (argarray[1]) strncpy(hotkeybuff,(UBYTE *)argarray[1],256);
if (argarray[2] && !stricmp((UBYTE *)argarray[2],"NO")) dontpop = 1;
FreeArgs(rdargs);
}
else
{
PrintFault(IoErr(),NULL);
cleanup(RETURN_ERROR);
}
}
strncat(windowtitle,hotkeybuff,100);
strcat(windowtitle,">");
if (!setupCX()) cleanup(RETURN_OK); /* return_ok because it failed 'cos XFH was already running */
InitXFHSemaphore();
if (!dontpop)
{
if (!openwindow()) closewindow();
}
do
{
windowsignal = (window ? 1L << window->UserPort->mp_SigBit : 0);
recsignal = Wait(windowsignal | cxsigflag | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F);
if (recsignal & cxsigflag)
{
while (cxport && !done && (cxmsg = (CxMsg *)GetMsg(cxport)))
{
switch(CxMsgType(cxmsg))
{
case CXM_IEVENT:
switch(CxMsgID(cxmsg))
{
case POP_KEY_ID:
if (!openwindow()) closewindow();
break;
}
break;
case CXM_COMMAND:
switch(CxMsgID(cxmsg))
{
case CXCMD_DISABLE:
ActivateCxObj(broker,0L);
break;
case CXCMD_ENABLE:
ActivateCxObj(broker,1L);
break;
case CXCMD_APPEAR:
case CXCMD_UNIQUE:
if (!openwindow()) closewindow();
break;
case CXCMD_DISAPPEAR:
closewindow();
break;
case CXCMD_KILL:
done = 1;
break;
}
break;
}
ReplyMsg((struct Message *)cxmsg);
}
}
if (recsignal & SIGBREAKF_CTRL_C)
done = 1;
if ((recsignal & SIGBREAKF_CTRL_F) && !done)
if (!openwindow()) closewindow();
if (recsignal & windowsignal)
{
while (window && !done && (msg = GT_GetIMsg(window->UserPort)))
{
cl = msg->Class;
code = msg->Code;
gadg = (struct Gadget *)msg->IAddress;
GT_ReplyIMsg(msg);
switch (cl)
{
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(window);
GT_EndRefresh(window,TRUE);
break;
case IDCMP_CLOSEWINDOW:
closewindow();
break;
case IDCMP_GADGETUP:
switch (gadg->GadgetID)
{
case DEVLISTID:
{
struct MyXFHNode *nd,*nextnd;
UWORD j = 0;
numselecteddevice = code;
nd = (struct MyXFHNode *)xfhlist.lh_Head;
while (j < code && (nextnd = (struct MyXFHNode *)nd->nd.ln_Succ))
{
nd = nextnd;
j++;
}
if (nd->nd.ln_Succ) selecteddevice = nd;
else /* /// this really shouldn't happen */
{
selecteddevice = NULL;
numselecteddevice = ~0L;
GT_SetGadgetAttrs(devlistgad,window,NULL,
GTLV_Selected,~0L,
TAG_DONE);
}
PrintInfoSelectedDevice();
}
break;
case LOWMEMID:
if (selecteddevice)
selecteddevice->xfh.xfh_LowMemory ^= 1;
break;
case AUTOPACKID:
if (selecteddevice)
{
selecteddevice->xfh.xfh_AutoPack ^= 1;
GT_SetGadgetAttrs(selectpackergad,window,NULL,
GA_Disabled,(LONG)!selecteddevice->xfh.xfh_AutoPack,
TAG_DONE);
}
break;
case SELECTPACKERID:
if (selecteddevice && displayedgads == 1)
{
struct MyXPINFO *nd,*nextnd;
UWORD j = 0;
/* find the packer associated with selected device */
nd = (struct MyXPINFO *)packerlist.lh_Head;
j = 0;
selectedpacker = NULL;
numselectedpacker = ~0L;
while ((nextnd = (struct MyXPINFO *)nd->nd.ln_Succ))
{
if (!strcmp((UBYTE *)&selecteddevice->xfh.xfh_PackerID,nd->nd.ln_Name))
{
selectedpacker = nd;
numselectedpacker = j;
if ((selectedpacker->xpinfo.DefMode = selecteddevice->xfh.xfh_PackMode) > 100)
{
XPINFO xpinfo;
if (!XpkQueryTags(
XPK_PackerQuery,&xpinfo,
XPK_PackMethod,(UBYTE *)&selecteddevice->xfh.xfh_PackerID,
TAG_DONE))
selectedpacker->xpinfo.DefMode = xpinfo.DefMode;
}
break;
}
nd = nextnd;
j++;
}
if (createsecondarygadgets())
{
RemoveGList(window,glist1,-1);
ClearWindow(window);
AddGList(window,glist2,-1,-1,NULL);
RefreshGList(glist2,window,NULL,-1);
GT_RefreshWindow(window,NULL);
displayedgads = 2;
PrintInfoSelectedPacker();
}
}
break;
case PACKERLISTID:
{
struct MyXPINFO *nd,*nextnd;
UWORD j = 0;
numselectedpacker = code;
nd = (struct MyXPINFO *)packerlist.lh_Head;
while (j < code && (nextnd = (struct MyXPINFO *)nd->nd.ln_Succ))
{
nd = nextnd;
j++;
}
if (nd->nd.ln_Succ) selectedpacker = nd;
else /* /// this really shouldn't happen */
{
selectedpacker = NULL;
numselectedpacker = ~0L;
GT_SetGadgetAttrs(packerlistgad,window,NULL,
GTLV_Selected,~0L,
TAG_DONE);
}
PrintInfoSelectedPacker();
}
break;
case OKID:
if (selecteddevice)
{
if (selectedpacker)
{
strcpy((UBYTE *)&selecteddevice->xfh.xfh_PackerID,selectedpacker->nd.ln_Name);
if (selectedpacker->xpinfo.Flags & XPKIF_MODES)
selecteddevice->xfh.xfh_PackMode = selectedpacker->xpinfo.DefMode;
else selecteddevice->xfh.xfh_PackMode = (UBYTE)~0;
}
else selecteddevice->xfh.xfh_PackerID = NULL;
}
case CANCELID:
if (displayedgads == 2)
{
RemoveGList(window,glist2,-1);
ClearWindow(window);
AddGList(window,glist1,-1,-1,NULL);
RefreshGList(glist1,window,NULL,-1);
GT_RefreshWindow(window,NULL);
if (glist2) FreeGadgets(glist2);
glist2 = NULL;
displayedgads = 1;
PrintInfoSelectedDevice();
}
break;
}
break;
case IDCMP_MOUSEMOVE:
switch (gadg->GadgetID)
{
case EFFICID:
if (selectedpacker) selectedpacker->xpinfo.DefMode = code;
PrintInfoSelectedMode();
break;
}
break;
case IDCMP_MENUPICK:
while (code != MENUNULL && !done)
{
struct MenuItem *item;
item = ItemAddress(menu,code);
switch((ULONG)MENU_USERDATA(item))
{
case MEN_HIDE:
closewindow();
break;
case MEN_QUIT:
done = 1;
break;
case MEN_SAVE:
saveconfig();
break;
}
/* ensure that the menu is still there (in case the window closed) */
if (menu) code = item->NextSelect;
else code = MENUNULL;
}
break;
}
}
}
} while (!done);
cleanup(RETURN_OK);
}
struct Window *openwindow(VOID)
{
static WORD zoom[4] = { 0,0,200,-1 };
if (window)
{
ActivateWindow(window);
WindowToFront(window);
if (window->Flags & WFLG_ZOOMED) ZipWindow(window);
return(window);
}
if (!(topazfont = OpenFont(&tanormal))) return(0);
if (!(screen = LockPubScreen(NULL)))
return(0);
if (IntuitionBase->LibNode.lib_Version >= 39) zoom[0] = zoom[1] = -1;
else zoom[1] = screen->BarHeight + 1;
zoom[3] = screen->WBorTop + screen->Font->ta_YSize + 1;
if (winleft == -1) winleft = 0;
if (wintop == -1) wintop = screen->BarHeight + 1;
if (!(window = OpenWindowTags(NULL,
WA_Left,winleft,
WA_Top,wintop,
WA_Width,WINDOWWIDTH,
WA_InnerHeight,140L,
WA_Zoom,zoom,
WA_DragBar,1L,
WA_DepthGadget,1L,
WA_CloseGadget,1L,
WA_IDCMP,(ULONG)BUTTONIDCMP | LISTVIEWIDCMP | CHECKBOXIDCMP | SLIDERIDCMP
| IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_REFRESHWINDOW,
WA_Activate,1L,
WA_SimpleRefresh,1L,
WA_Title,windowtitle,
WA_PubScreen,screen,
WA_NewLookMenus,1L,
TAG_DONE)) || !(vi = GetVisualInfo(window->WScreen,NULL)))
return(0);
SetFont(window->RPort,topazfont);
if (!(menu = CreateMenusA(menudef,TAG_DONE)) || !LayoutMenus(menu,vi,
GTMN_NewLookMenus,1L,
TAG_DONE))
return(0);
SetMenuStrip(window,menu);
if (!createmaingadgets()) return(0);
AddGList(window,glist1,-1,-1,NULL);
RefreshGList(glist1,window,NULL,-1);
GT_RefreshWindow(window,NULL);
displayedgads = 1;
builddevslist();
buildpackerslist();
GT_SetGadgetAttrs(devlistgad,window,NULL,
GTLV_Labels,&xfhlist,
TAG_DONE);
return(window);
}
LONG createmaingadgets(VOID)
{
struct NewGadget newg;
struct Gadget *gadg;
if (!(gadg = CreateContext(&glist1)))
return(0);
newg.ng_Width = WINDOWWIDTH-24;
newg.ng_Height = 70;
newg.ng_GadgetText = "XFH Device";
newg.ng_TextAttr = &tanormal;
newg.ng_VisualInfo = vi;
newg.ng_GadgetID = DEVLISTID;
newg.ng_Flags = 0;
newg.ng_LeftEdge = 12;
newg.ng_TopEdge = window->BorderTop + 16;
if (!(devlistgad = gadg = CreateGadget(LISTVIEW_KIND,gadg,&newg,
GTLV_ShowSelected,0L,
GTLV_ScrollWidth,18L,
LAYOUTA_Spacing,1L,
TAG_DONE)))
return(0);
newg.ng_GadgetText = "Low Memory";
newg.ng_GadgetID = LOWMEMID;
newg.ng_Flags = PLACETEXT_RIGHT;
newg.ng_TopEdge = window->BorderTop + 92;
if (!(lowmemgad = gadg = CreateGadget(CHECKBOX_KIND,gadg,&newg,
GA_Disabled,1L,
TAG_DONE)))
return(0);
newg.ng_GadgetText = "Compression";
newg.ng_GadgetID = AUTOPACKID;
newg.ng_LeftEdge = 242;
if (!(autopackgad = gadg = CreateGadget(CHECKBOX_KIND,gadg,&newg,
GA_Disabled,1L,
TAG_DONE)))
return(0);
newg.ng_Width = 212;
newg.ng_Flags = 0;
newg.ng_GadgetText = "Select Compressor...";
newg.ng_GadgetID = SELECTPACKERID;
newg.ng_Height = 14;
newg.ng_TopEdge = window->BorderTop + 105;
if (!(selectpackergad = gadg = CreateGadget(BUTTON_KIND,gadg,&newg,
GA_Disabled,1L,
TAG_DONE)))
return(0);
newg.ng_GadgetText = "Compressor:";
newg.ng_GadgetID = 0;
newg.ng_TopEdge = window->BorderTop + 121;
if (!(packernamegad = gadg = CreateGadget(TEXT_KIND,gadg,&newg,
GTTX_Border,1L,
TAG_DONE)))
return(0);
return(1);
}
LONG createsecondarygadgets(VOID)
{
struct NewGadget newg;
struct Gadget *gadg;
if (!(gadg = CreateContext(&glist2)))
goto fail;
newg.ng_Width = 110;
newg.ng_Height = 100;
newg.ng_GadgetText = "Compressor";
newg.ng_TextAttr = &tanormal;
newg.ng_VisualInfo = vi;
newg.ng_GadgetID = PACKERLISTID;
newg.ng_Flags = 0;
newg.ng_LeftEdge = 12;
newg.ng_TopEdge = window->BorderTop + 16;
if (!(packerlistgad = gadg = CreateGadget(LISTVIEW_KIND,gadg,&newg,
GTLV_Labels,&packerlist,
GTLV_Selected,numselectedpacker,
GTLV_ShowSelected,0L,
GTLV_ScrollWidth,18L,
LAYOUTA_Spacing,1L,
TAG_DONE)))
goto fail;
newg.ng_Width = 87;
newg.ng_Height = 14;
newg.ng_GadgetText = "OK";
newg.ng_GadgetID = OKID;
newg.ng_TopEdge = window->Height - 19;
if (!(gadg = CreateGadget(BUTTON_KIND,gadg,&newg,
TAG_DONE)))
goto fail;
newg.ng_GadgetText = "Cancel";
newg.ng_GadgetID = CANCELID;
newg.ng_LeftEdge = WINDOWWIDTH - 99;
if (!(gadg = CreateGadget(BUTTON_KIND,gadg,&newg,
TAG_DONE)))
goto fail;
newg.ng_Width = PACKERDESCCHARS*8+8;
newg.ng_Height = 40;
newg.ng_GadgetText = "Description";
newg.ng_GadgetID = 0;
newg.ng_Flags = PLACETEXT_ABOVE;
newg.ng_LeftEdge = WINDOWWIDTH - PACKERDESCCHARS*8-8-12;
newg.ng_TopEdge = window->BorderTop + 16;
if (!(gadg = CreateGadget(TEXT_KIND,gadg,&newg,
GTTX_Border,1L,
TAG_DONE)))
goto fail;
newg.ng_Width = PACKERDESCCHARS*8;
newg.ng_Height = 14;
newg.ng_GadgetText = NULL;
newg.ng_Flags = 0;
newg.ng_LeftEdge = WINDOWWIDTH - PACKERDESCCHARS*8-4-12;
newg.ng_TopEdge = window->BorderTop + 18;
if (!(desc1gad = gadg = CreateGadget(TEXT_KIND,gadg,&newg,
TAG_DONE)))
goto fail;
newg.ng_TopEdge = window->BorderTop + 29;
if (!(desc2gad = gadg = CreateGadget(TEXT_KIND,gadg,&newg,
TAG_DONE)))
goto fail;
newg.ng_TopEdge = window->BorderTop + 40;
if (!(desc3gad = gadg = CreateGadget(TEXT_KIND,gadg,&newg,
TAG_DONE)))
goto fail;
newg.ng_Width = 140;
newg.ng_Height = 11;
newg.ng_GadgetText = "Efficiency: ";
newg.ng_GadgetID = EFFICID;
newg.ng_LeftEdge = WINDOWWIDTH - 140-12;
newg.ng_TopEdge = window->BorderTop + 62;
if (!(efficgad = gadg = CreateGadget(SLIDER_KIND,gadg,&newg,
GTSL_Min,0L,
GTSL_Max,100L,
GTSL_LevelFormat,"%3ld%%",
GTSL_MaxLevelLen,4L,
GTSL_Level,(LONG)(selectedpacker ? selectedpacker->xpinfo.DefMode : 50),
GA_Disabled,(LONG)!(selectedpacker && selectedpacker->xpinfo.Flags & XPKIF_MODES),
TAG_DONE)))
goto fail;
newg.ng_Width = 80;
newg.ng_Height = 14;
newg.ng_GadgetText = "Mode:";
newg.ng_TopEdge = window->BorderTop + 75;
modestr[0] = 0;
if (!(modegad = gadg = CreateGadget(TEXT_KIND,gadg,&newg,
TAG_DONE)))
goto fail;
newg.ng_Width = 40;
newg.ng_GadgetText = "Compression:";
newg.ng_TopEdge = window->BorderTop + 85;
cfstr[0] = 0;
if (!(cfgad = gadg = CreateGadget(TEXT_KIND,gadg,&newg,
TAG_DONE)))
goto fail;
newg.ng_Width = 80;
newg.ng_GadgetText = "Compression Speed:";
newg.ng_TopEdge = window->BorderTop + 95;
psstr[0] = 0;
if (!(psgad = gadg = CreateGadget(TEXT_KIND,gadg,&newg,
TAG_DONE)))
goto fail;
newg.ng_GadgetText = "Decompression Speed:";
newg.ng_TopEdge = window->BorderTop + 105;
usstr[0] = 0;
if (!(usgad = gadg = CreateGadget(TEXT_KIND,gadg,&newg,
TAG_DONE)))
goto fail;
return(1);
fail:
if (glist2) FreeGadgets(glist2);
glist2 = NULL;
return(0);
}
VOID closewindow(VOID)
{
if (menu)
{
ClearMenuStrip(window);
FreeMenus(menu);
menu = NULL;
}
if (window)
{
winleft = window->LeftEdge;
wintop = window->TopEdge;
CloseWindow(window);
window = NULL;
}
if (glist1)
{
FreeGadgets(glist1);
glist1 = NULL;
}
if (glist2)
{
FreeGadgets(glist2);
glist2 = NULL;
}
if (vi)
{
FreeVisualInfo(vi);
vi = NULL;
}
if (screen)
{
UnlockPubScreen(NULL,screen);
screen = NULL;
}
if (topazfont)
{
CloseFont(topazfont);
topazfont = NULL;
}
/* signal XFH handlers about changes */
{
struct MyXFHNode *nd,*nextnd;
nd = (struct MyXFHNode *)xfhlist.lh_Head;
while (nextnd = (struct MyXFHNode *)nd->nd.ln_Succ)
{
updatesemaphore(nd);
nd = nextnd;
}
}
FreeList(&xfhlist);
selecteddevice = NULL;
numselecteddevice = ~0;
FreeList(&packerlist);
}
VOID builddevslist(VOID)
{
struct XFHSemaphore *sem;
if (sem = GetSemaphore())
{
struct MyXFHNode *node;
struct XFHNode *se,*nse;
se = (struct XFHNode *)sem->xfh_DeviceList.lh_Head;
while (nse = (struct XFHNode *)se->xfh_Node.ln_Succ)
{
if (node = AllocVec(sizeof(struct MyXFHNode) + strlen(se->xfh_Node.ln_Name)
+ DEVLISTCHARS + 2,MEMF_CLEAR))
{
CopyMem(se,&node->xfh,sizeof(struct XFHNode));
node->nd.ln_Name = (UBYTE *)(node + 1);
node->xfh.xfh_Node.ln_Name = node->nd.ln_Name + DEVLISTCHARS + 1;
strncpy(node->nd.ln_Name,se->xfh_Node.ln_Name,10);
strcpy(node->xfh.xfh_Node.ln_Name,se->xfh_Node.ln_Name);
AddAlpha(&xfhlist,node);
}
se = nse;
}
ReleaseSemaphore(sem);
}
{
struct MyXFHNode *se,*nse;
se = (struct MyXFHNode *)xfhlist.lh_Head;
while (nse = (struct MyXFHNode *)se->nd.ln_Succ)
{
if (se->xfh.xfh_RootLock)
{
UBYTE *buf = se->nd.ln_Name;
strcat(buf," ");
buf[10] = '(';
NameFromLock(se->xfh.xfh_RootLock,&buf[11],DEVLISTCHARS-12);
strcat(buf,")");
}
se = nse;
}
}
}
VOID buildpackerslist(VOID)
{
XPLIST *list;
if (list = AllocMem(sizeof(XPLIST),0))
{
if (!XpkQueryTags(
XPK_PackersQuery,list,
TAG_DONE))
{
ULONG i;
for (i = 0;i < list->NumPackers;i++)
{
XPINFO xpinfo;
if (!XpkQueryTags(
XPK_PackerQuery,&xpinfo,
XPK_PackMethod,list->Packer[i],
TAG_DONE) && !(xpinfo.Flags & XPKIF_NEEDPASSWD))
{
struct MyXPINFO *node;
if (node = AllocVec(sizeof(struct MyXPINFO) + 4 + 1,MEMF_CLEAR))
{
node->nd.ln_Name = (UBYTE *)(node + 1);
strncpy(node->nd.ln_Name,(UBYTE *)list->Packer[i],4);
CopyMem(&xpinfo,&node->xpinfo,sizeof(XPINFO));
AddAlpha(&packerlist,node);
}
}
}
}
FreeMem(list,sizeof(XPLIST));
}
}
VOID ClearWindow(struct Window *win)
{
ULONG minx,maxx,miny,maxy;
minx = win->BorderLeft;
miny = win->BorderTop;
maxx = win->Width - win->BorderRight - 1;
maxy = win->Height - win->BorderBottom - 1;
if (minx <= maxx && miny <= maxy)
EraseRect(win->RPort,minx,miny,maxx,maxy);
}
VOID PrintInfoSelectedDevice(VOID)
{
static UBYTE packername[10];
packername[0] = 0;
if (selecteddevice)
{
GT_SetGadgetAttrs(lowmemgad,window,NULL,
GTCB_Checked,(LONG)selecteddevice->xfh.xfh_LowMemory,
GA_Disabled,0L,
TAG_DONE);
GT_SetGadgetAttrs(autopackgad,window,NULL,
GTCB_Checked,(LONG)selecteddevice->xfh.xfh_AutoPack,
GA_Disabled,0L,
TAG_DONE);
if (selecteddevice->xfh.xfh_PackerID)
sprintf(packername,(selecteddevice->xfh.xfh_PackMode <= 100 ? "%s.%ld" : "%s"),(UBYTE *)&selecteddevice->xfh.xfh_PackerID,(LONG)selecteddevice->xfh.xfh_PackMode);
}
else
{
GT_SetGadgetAttrs(lowmemgad,window,NULL,
GA_Disabled,1L,
TAG_DONE);
GT_SetGadgetAttrs(autopackgad,window,NULL,
GA_Disabled,1L,
TAG_DONE);
}
GT_SetGadgetAttrs(selectpackergad,window,NULL,
GA_Disabled,(LONG)!(selecteddevice && selecteddevice->xfh.xfh_AutoPack),
TAG_DONE);
GT_SetGadgetAttrs(packernamegad,window,NULL,
GTTX_Text,packername,
TAG_DONE);
}
VOID PrintInfoSelectedPacker(VOID)
{
static UBYTE descr2[PACKERDESCCHARS+1],descr3[PACKERDESCCHARS+1];
GT_SetGadgetAttrs(efficgad,window,NULL,
GTSL_Level,(LONG)(selectedpacker ? selectedpacker->xpinfo.DefMode : 50),
GA_Disabled,(LONG)!(selectedpacker && selectedpacker->xpinfo.Flags & XPKIF_MODES),
TAG_DONE);
GT_SetGadgetAttrs(desc1gad,window,NULL,
GTTX_Text,(selectedpacker ? selectedpacker->xpinfo.LongName : NULL),
TAG_DONE);
if (selectedpacker)
{
descr2[PACKERDESCCHARS] = 0;
strncpy(descr2,(UBYTE *)selectedpacker->xpinfo.Description,PACKERDESCCHARS);
if (strlen((UBYTE *)selectedpacker->xpinfo.Description) > PACKERDESCCHARS)
{
WORD l = PACKERDESCCHARS;
while(selectedpacker->xpinfo.Description[l] != ' ') l--;
descr2[l] = 0;
strncpy(descr3,(UBYTE *)&selectedpacker->xpinfo.Description[l+1],PACKERDESCCHARS);
descr3[PACKERDESCCHARS] = 0;
}
else descr3[0] = 0;
}
else descr2[0] = descr3[0] = 0;
GT_SetGadgetAttrs(desc2gad,window,NULL,
GTTX_Text,descr2,
TAG_DONE);
GT_SetGadgetAttrs(desc3gad,window,NULL,
GTTX_Text,descr3,
TAG_DONE);
PrintInfoSelectedMode();
}
VOID PrintInfoSelectedMode(VOID)
{
XMINFO xminfo;
UBYTE newmode[10],newcf[5],newps[20],newus[20];
if (selectedpacker && !XpkQueryTags(
XPK_ModeQuery,&xminfo,
XPK_PackMethod,selectedpacker->nd.ln_Name,
XPK_PackMode,(LONG)selectedpacker->xpinfo.DefMode,
TAG_DONE))
{
strcpy(newmode,xminfo.Description);
sprintf(newcf,"%ld%%",(LONG)xminfo.Ratio/10);
sprintf(newps,"%ld K/s",xminfo.PackSpeed);
sprintf(newus,"%ld K/s",xminfo.UnpackSpeed);
}
else newmode[0] = newcf[0] = newps[0] = newus[0] = 0;
if (strcmp(modestr,newmode))
{
strcpy(modestr,newmode);
GT_SetGadgetAttrs(modegad,window,NULL,
GTTX_Text,modestr,
TAG_DONE);
}
if (strcmp(cfstr,newcf))
{
strcpy(cfstr,newcf);
GT_SetGadgetAttrs(cfgad,window,NULL,
GTTX_Text,cfstr,
TAG_DONE);
}
if (strcmp(psstr,newps))
{
strncpy(psstr,newps,9);
GT_SetGadgetAttrs(psgad,window,NULL,
GTTX_Text,psstr,
TAG_DONE);
}
if (strcmp(usstr,newus))
{
strncpy(usstr,newus,9);
GT_SetGadgetAttrs(usgad,window,NULL,
GTTX_Text,usstr,
TAG_DONE);
}
}
/* Lock the semaphore and return a pointer to it, or NULL if it isn't there. */
/* If it can't find it, will try to create a new one; so this function will */
/* fail only due to severe low memory conditions */
/* When done with the list, the semaphore must be freed with ReleaseSemaphore() */
struct XFHSemaphore *GetSemaphore(VOID)
{
struct XFHSemaphore *sem;
static UBYTE xfhsemaphorename[] = XFHSEMAPHORENAME;
Forbid();
if (!(sem = (struct XFHSemaphore *)FindSemaphore(xfhsemaphorename)) &&
(sem = AllocMem(sizeof(struct XFHSemaphore) + sizeof(xfhsemaphorename) + 1,MEMF_CLEAR | MEMF_PUBLIC)))
{
sem->xfh_Length = sizeof(struct XFHSemaphore);
sem->xfh_Semaphore.ss_Link.ln_Name = ((UBYTE *)(sem + 1));
strcpy(sem->xfh_Semaphore.ss_Link.ln_Name,xfhsemaphorename);
NewList(&sem->xfh_DeviceList);
AddSemaphore(sem);
}
Permit();
/* out of Forbid() because the semaphore is guaranteed not to be removed */
if (sem) ObtainSemaphore(sem);
return(sem);
}
VOID InitXFHSemaphore(VOID)
{
struct DiskObject *dskobj;
if (dskobj = GetDiskObject(iconname))
{
struct XFHSemaphore *sem;
if (sem = GetSemaphore())
{
UBYTE **ttp;
ttp = dskobj->do_ToolTypes;
while (*ttp)
{
UBYTE *tt;
tt = *ttp;
if (tt[0] == '«')
{
UBYTE *st1,*st2,*st3,*st4,*st5;
tt++;
st5 = 0;
if (st1 = strchr(tt,','))
{
*(st1++) = 0;
if (st2 = strchr(st1,','))
{
*(st2++) = 0;
if (st3 = strchr(st2,','))
{
*(st3++) = 0;
if (st4 = strchr(st3,'.'))
{
*(st4++) = 0;
st5 = strchr(st4,'»');
}
/* handle packerIDs with no explicit mode */
else if (st4 = strchr(st3,'»'))
{
*st4 = 0;
st5 = st4;
}
}
}
}
if (st5)
{
struct XFHNode *node;
if (!(node = (struct XFHNode *)FindName(&sem->xfh_DeviceList,tt))
&& (node = AllocMem(sizeof(struct XFHNode) + strlen(tt) + 1,MEMF_CLEAR | MEMF_PUBLIC)))
{
node->xfh_Length = sizeof(struct XFHNode);
node->xfh_Node.ln_Name = (UBYTE *)(node + 1);
strcpy(node->xfh_Node.ln_Name,tt);
AddTail(&sem->xfh_DeviceList,node);
}
if (node)
{
node->xfh_LowMemory = !stricmp(st1,lowmemtxt);
node->xfh_AutoPack = !stricmp(st2,compresstxt);
if (strlen(st3) == 4)
{
LONG val;
strcpy((UBYTE *)&node->xfh_PackerID,st3);
if (st4 != st5) /* check if there's an explicit mode */
{
StrToLong(st4,&val);
node->xfh_PackMode = val;
}
else node->xfh_PackMode = 0xff;
}
else node->xfh_PackerID = NULL;
notifyhandler(node);
}
}
}
ttp++;
}
ReleaseSemaphore(sem);
}
FreeDiskObject(dskobj);
}
}
VOID saveconfig(VOID)
{
struct DiskObject *dskobj;
if (dskobj = GetDiskObject(iconname))
{
UBYTE **ttp;
UBYTE *newttp[128]; /* /// reasonable limitation */
WORD ttcnt = 0;
struct MyXFHNode *nd,*nextnd;
struct Remember *RememberKey = NULL;
nd = (struct MyXFHNode *)xfhlist.lh_Head;
while (nextnd = (struct MyXFHNode *)nd->nd.ln_Succ)
{
UBYTE *buf;
if (buf = AllocRemember(&RememberKey,100,0))
{
sprintf(buf,((nd->xfh.xfh_PackerID && nd->xfh.xfh_PackMode <= 100)
? "«%s,%s,%s,%s.%ld»" : "«%s,%s,%s,%s»"),
nd->xfh.xfh_Node.ln_Name,
nd->xfh.xfh_LowMemory ? lowmemtxt : "",
nd->xfh.xfh_AutoPack ? compresstxt : "",
(UBYTE *)&nd->xfh.xfh_PackerID,
(LONG)nd->xfh.xfh_PackMode);
newttp[ttcnt++] = buf;
}
nd = nextnd;
}
/* copy remaining tooltypes */
ttp = dskobj->do_ToolTypes;
while (*ttp)
{
if (**ttp != (UBYTE)'«')
newttp[ttcnt++] = *ttp;
ttp++;
}
newttp[ttcnt] = NULL;
ttp = dskobj->do_ToolTypes;
dskobj->do_ToolTypes = newttp;
PutDiskObject(iconname,dskobj);
FreeRemember(&RememberKey,TRUE);
dskobj->do_ToolTypes = ttp;
FreeDiskObject(dskobj);
}
}
/* this function updates the semaphore list contents and signals the xfh */
/* task if mounted */
VOID updatesemaphore(struct MyXFHNode *nd)
{
struct XFHSemaphore *sem;
if (sem = GetSemaphore())
{
struct XFHNode *ond;
if (ond = (struct XFHNode *)FindName(&sem->xfh_DeviceList,nd->xfh.xfh_Node.ln_Name))
{
ond->xfh_AutoPack = nd->xfh.xfh_AutoPack;
ond->xfh_PackerID = nd->xfh.xfh_PackerID;
ond->xfh_PackMode = nd->xfh.xfh_PackMode;
ond->xfh_LowMemory = nd->xfh.xfh_LowMemory;
notifyhandler(ond);
}
ReleaseSemaphore(sem);
}
}
VOID notifyhandler(struct XFHNode *node)
{
if (node->xfh_Handler) Signal(node->xfh_Handler->mp_SigTask,SIGBREAKF_CTRL_F);
}
VOID AddAlpha(struct List *list,struct Node *node)
{
struct Node *nd;
nd = list->lh_TailPred;
while (nd != (struct Node *)list &&
stricmp(nd->ln_Name,node->ln_Name) > 0) nd = nd->ln_Pred;
Insert(list,node,nd);
}
VOID FreeList(struct List *list)
{
struct Node *nd,*nextnd;
nd = list->lh_Head;
while (nextnd = nd->ln_Succ)
{
Remove(nd);
FreeVec(nd);
nd = nextnd;
}
}
VOID cleanup(LONG code)
{
extern struct WBStartup *WBenchMsg;
shutdownCX();
closewindow();
if (XpkBase) CloseLibrary(XpkBase);
if (CxBase) CloseLibrary(CxBase);
if (IconBase) CloseLibrary(IconBase);
if (GadToolsBase) CloseLibrary(GadToolsBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (GfxBase) CloseLibrary(GfxBase);
if (WBenchMsg)
{
Forbid();
ReplyMsg(WBenchMsg);
}
_XCEXIT(code);
}
BOOL setupCX(VOID)
{
if (!(cxport = CreateMsgPort())) return(0);
cxsigflag = 1L << cxport->mp_SigBit; /* Create signal mask for Wait */
mynb.nb_Port = cxport;
if (!(broker = CxBroker(&mynb,NULL)))
{
shutdownCX();
return(0);
}
/* install a hotkey for popping up window */
AttachCxObj(broker,HotKey(hotkeybuff,cxport,POP_KEY_ID));
/* All went well so activate our broker */
ActivateCxObj(broker,1L);
return(1);
}
VOID shutdownCX(VOID)
{
struct Message *msg;
if (cxport)
{
DeleteCxObjAll(broker); /* safe, even if NULL */
/* now that messages are shut off, clear port */
while (msg = GetMsg(cxport)) ReplyMsg(msg);
DeleteMsgPort(cxport);
cxport = NULL;
cxsigflag = 0;
broker = NULL;
}
}